package db

import (
	"fmt"
	"time"

	"gorm.io/gorm"
)

type TrashListResult struct {
	Files []UserFile
	Total int64
}

// GetUserTrashList 获取用户回收站文件列表（分页）
func GetUserTrashList(username string, page, pageSize int) ([]UserFile, int64, error) {
	var files []UserFile
	var total int64

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 先获取总数
	err := DB.Model(&UserFile{}).
		Where("user_name = ? AND status = 1", username).
		Count(&total).Error
	if err != nil {
		return nil, 0, err
	}

	// 获取分页数据
	err = DB.Where("user_name = ? AND status = 1", username).
		Order("deleted_at desc"). // 按删除时间倒序
		Offset(offset).
		Limit(pageSize).
		Find(&files).Error
	if err != nil {
		return nil, 0, err
	}

	return files, total, nil
}

// 恢复文件
func RestoreUserFile(username, filesha1 string) error {
	return DB.Transaction(func(tx *gorm.DB) error {
		// 查找文件
		var file UserFile
		if err := tx.Where("user_name = ? AND file_sha1 = ? AND status = 1",
			username, filesha1).First(&file).Error; err != nil {
			return fmt.Errorf("文件不存在或无权限访问")
		}

		// 如果是文件夹，递归恢复所有子文件
		if file.IsFolder {
			if err := tx.Model(&UserFile{}).
				Where("user_name = ? AND parent_path LIKE ? AND status = 1",
					username, file.ParentPath+file.FileName+"/%").
				Updates(map[string]interface{}{
					"status":     0,
					"deleted_at": nil,
				}).Error; err != nil {
				return err
			}
		}

		// 恢复文件本身
		if err := tx.Model(&file).Updates(map[string]interface{}{
			"status":     0,
			"deleted_at": nil,
		}).Error; err != nil {
			return err
		}

		return nil
	})
}

// 永久删除文件
func PermanentlyDeleteUserFile(username, filesha1 string) error {
	return DB.Transaction(func(tx *gorm.DB) error {
		// 查找文件
		var file UserFile
		if err := tx.Where("user_name = ? AND file_sha1 = ?",
			username, filesha1).First(&file).Error; err != nil {
			return fmt.Errorf("文件不存在或无权限访问")
		}

		// 如果是文件夹，递归删除所有子文件
		if file.IsFolder {
			if err := tx.Unscoped().Where(
				"user_name = ? AND parent_path LIKE ?",
				username, file.ParentPath+file.FileName+"/%",
			).Delete(&UserFile{}).Error; err != nil {
				return err
			}
		}

		// 永久删除文件本身
		if err := tx.Unscoped().Delete(&file).Error; err != nil {
			return err
		}

		return nil
	})
}

// 定期物理删除过期数据
func CleanupDeletedFiles(daysToKeep int) error {
	deadline := time.Now().AddDate(0, 0, -daysToKeep)
	return DB.Unscoped().
		Where("status = 1 AND deleted_at < ?", deadline).
		Delete(&UserFile{}).Error
}

// DeleteShortcut 删除快捷方式并减少源文件引用计数
func DeleteShortcut(filename string, filehash string) (*UserFile, error) {
    var originalFile UserFile // 在事务外部声明

    err := DB.Transaction(func(tx *gorm.DB) error {
        // 1. 获取源文件信息（按上传时间最早的）
        if err := tx.Where("file_sha1 = ? AND is_original = ?", 
            filehash, true).First(&originalFile).Error; err != nil {
            return fmt.Errorf("找不到源文件: %v", err)
        }

        // 2. 减少源文件的引用计数
        if err := tx.Model(&originalFile).
            UpdateColumn("reference_count", 
                gorm.Expr("reference_count - ?", 1)).Error; err != nil {
            return fmt.Errorf("更新引用计数失败: %v", err)
        }

        // 3. 删除当前快捷方式记录
        if err := tx.Where("file_name = ? AND file_sha1 = ?", 
            filename, filehash).Delete(&UserFile{}).Error; err != nil {
            return fmt.Errorf("删除快捷方式失败: %v", err)
        }

		// 重新加载 originalFile 以获取最新的 reference_count
		if err := tx.Where("file_sha1 = ? AND is_original = ?", filehash, true).First(&originalFile).Error; err != nil {
			return fmt.Errorf("重新加载源文件失败: %v", err)
		}

        return nil
    })

    if err != nil {
        return nil, err
    }

    return &originalFile, nil // 返回引用
}

// DecrementReferenceAndUpdateStatus 减少引用计数并更新状态为2
func DecrementReferenceAndUpdateStatus(username string, fileHash string) error {
	return DB.Transaction(func(tx *gorm.DB) error {
		var file UserFile
		if err := tx.Where("user_name = ? AND file_sha1 = ? AND status = 1",
			username, fileHash).First(&file).Error; err != nil {
			return err
		}

		// 更新引用计数和状态
		if err := tx.Model(&file).Updates(map[string]interface{}{
			"reference_count": gorm.Expr("reference_count - ?", 1),
			"status":          2, // 设置状态为2，使其在回收站中不可见
		}).Error; err != nil {
			return err
		}

		return nil
	})
}
